<?php
require_once dirname(__FILE__).'/straightforward-dependency-injection.php';

// Example 1, getting an unique instance of a class

class Example1 {
	function test() { echo 'Example1'.PHP_EOL; }
}

instance('Example1')->test();
var_export(instance('Example1') === instance('Example1'));
echo PHP_EOL;

// Example 2, getting an instance through the getInstance() method commonly used in the Singleton pattern

class Example2 {
	private static $instance = null;
	static function getInstance() { return self::$instance ? self::$instance : self::$instance = new Example2; }
	private function __construct() { }
	function test() { echo 'Example2'.PHP_EOL; }
}

instance('Example2')->test();
var_export(instance('Example2') === Example2::getInstance());
echo PHP_EOL;

// Example 3, requiring dependendies through the constructor arguments

class Example3A {
	var $b;
	function __construct(Example3B $b) { $this->b = $b; }
	function test() { $this->b->test(); }
}
class Example3B {
	function test() { echo 'Example3'.PHP_EOL; }
}

instance('Example3A')->test();
var_export(instance('Example3A')->b === instance('Example3B'));
echo PHP_EOL;

// Example 4, not working yet, recursiveness not solved

/*
class Example4A {
	var $b;
	function __construct(Example4B $b) { $this->b = $b; }
	function test() { $this->b->test(); }
	function testBack() { echo 'Example4'.PHP_EOL; }
}
class Example4B {
	var $a;
	function __construct(Example4A $a) { $this->a = $a; }
	function test() { $this->a->testBack(); }
}

instance('Example4A')->test();
var_export(instance('Example4A')->b === instance('Example4B'));
echo PHP_EOL;
var_export(instance('Example4B')->a === instance('Example4A'));
echo PHP_EOL;
*/

// Example 5, temporary solution to recursive dependency

class Example5A {
	var $b;
	function __construct() { $this->b = instance('Example5B'); }
	function test() { $this->b->test(); }
	function testBack() { echo 'Example5'.PHP_EOL; }
}
class Example5B {
	var $a;
	function __construct() { $this->a = instance('Example5A'); }
	function test() { $this->a->testBack(); }
}

instance('Example5A')->test();
var_export(instance('Example5A')->b === instance('Example5B'));
echo PHP_EOL;
var_export(instance('Example5B')->a === instance('Example5A'));
echo PHP_EOL;

// Example 6, getting an implementation of an interface

interface Example6 {
	function test();
}
class Example6Impl implements Example6 {
	function test() { echo 'Example6'.PHP_EOL; }
}

instance('Example6')->test();
var_export(instance('Example6') instanceof Example6Impl);
echo PHP_EOL;

// Example 7, getting an implementation of an abstract class

abstract class Example7 {
	abstract function test();
}
class Example7Impl extends Example7 {
	function test() { echo 'Example7'.PHP_EOL; }
}

instance('Example7')->test();
var_export(instance('Example7') instanceof Example7Impl);
echo PHP_EOL;
